﻿using System.IO.Compression;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Nodes;

namespace kugoudownload
{
    public class KugouHttpUtil
    {

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="searchKeyWord"></param>
        /// <param name="PageIndex"></param>
        /// <returns></returns>
        public List<string> Search(string searchKeyWord, int PageIndex)
        {
            List<string> singerlist = new List<string>();
            HttpWebResponse response;
            try
            {
                string t = (DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds.ToString();


                string[] sign_params = {"NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt", "bitrate=0", "callback=callback123",
                       "clienttime=" + t, "clientver=2000", "dfid=-", "inputtype=0", "iscorrection=1",
                       "isfuzzy=0",
                       "keyword=" + searchKeyWord, "mid=" + t, "page=" + PageIndex, "pagesize=10",
                       "platform=WebFilter", "privilege_filter=0", "srcappid=2919", "token=", "userid=0",
                       "uuid=" + t, "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt" };
                var sign_paramStr = string.Join("", sign_params);
                var signature = ToMD5(sign_paramStr);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"https://complexsearch.kugou.com/v2/search/song?callback=callback123&page={PageIndex}&keyword={searchKeyWord}&pagesize=10&bitrate=0&isfuzzy=0&inputtype=0&platform=WebFilter&userid=0&clientver=2000&iscorrection=1&privilege_filter=0&token=&srcappid=2919&clienttime={t}&mid={t}&uuid={t}&dfid=-&signature={signature}");

                request.UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36";

                response = (HttpWebResponse) request.GetResponse();

                var responseText = ReadResponse(response);
                var responseJson = responseText.Replace("callback123(", "").TrimEnd().TrimEnd(')');
                

                response.Close();
                var jsNode = JsonNode.Parse(responseJson);

                var lists = jsNode?["data"]?["lists"];
                if (lists is JsonNode)
                {
                    int index = 0;
                    foreach (var item in lists.AsArray())
                    {
                        index++;
                        if (item is JsonNode)
                        {
                            singerlist.Add(item.ToJsonString());
                            Console.WriteLine($"{index.ToString().PadLeft(2, '0')}  {item["FileName"]}");
                        }
                    }
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return singerlist;
        }


        /// <summary>
        /// 下载
        /// </summary>
        /// <param name="song_info"></param>
        /// <returns></returns>
        public bool Download(string song_info_str)
        {
            try
            {
                var song_info = JsonNode.Parse(song_info_str);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"https://wwwapi.kugou.com/yy/index.php?r=play%2Fgetdata&callback=jQuery191035601158181920933_1653052693184&hash={song_info["FileHash"]}&dfid=2mSZvv2GejpK2VDsgh0K7U0O&appid=1014&mid=c18aeb062e34929c6e90e3af8f7e2512&platid=4&album_id={song_info["AlbumID"]}&_=1653050047389");

                request.UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36";

                var response = (HttpWebResponse) request.GetResponse();
                var responseText = ReadResponse(response);
                var responseJson = responseText.Substring(42).TrimEnd().TrimEnd(';').TrimEnd(')');
                var jsNode=JsonNode.Parse(responseJson);
                string fileUrl = jsNode["data"]?["play_url"].ToString();
                DownloadUrl(fileUrl, jsNode["data"]["audio_name"].ToString()+".mp3");
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return false;
        }

        /// <summary>
        /// 执行下载操作
        /// </summary>
        /// <param name="url"></param>
        /// <param name="objname"></param>
        /// <returns></returns>
        private void DownloadUrl(string url, string objname)
        {

            WebClient wc = new WebClient();
            bool reslut = false;
            var path = Path.Combine(System.Environment.CurrentDirectory+ @"\music", objname);

            try
            {

                Stream stream = wc.OpenRead(url);
                stream.Close();  //以及释放内存  
                wc.Dispose();
                if (!Directory.Exists(Path.GetDirectoryName(path)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                }
                wc.DownloadFile(url, path);
                Console.WriteLine(path);
                reslut = true;
            }
            catch (Exception e)
            {
                Console.WriteLine($"[Erroe]{url}:{e.Message}");
            }
        }

        /// <summary>
        /// 下载列表
        /// </summary>
        /// <param name="list"></param>
        public void DownloadAll(List<string> list)
        {
            for (int i = 0; i < list.Count(); i++)
            {
                Download(list[i]);
                Thread.Sleep(300);
            }
        }



        private string ReadResponse(HttpWebResponse response)
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                Stream streamToRead = responseStream;
                if (response.ContentEncoding.ToLower().Contains("gzip"))
                {
                    streamToRead = new GZipStream(streamToRead, CompressionMode.Decompress);
                }
                else if (response.ContentEncoding.ToLower().Contains("deflate"))
                {
                    streamToRead = new DeflateStream(streamToRead, CompressionMode.Decompress);
                }

                using (StreamReader streamReader = new StreamReader(streamToRead, Encoding.UTF8))
                {
                    return streamReader.ReadToEnd();
                }
            }
        }

        private string ToMD5(string sDataIn)
        {

            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            byte[] bytValue, bytHash;

            bytValue = System.Text.Encoding.UTF8.GetBytes(sDataIn);

            bytHash = md5.ComputeHash(bytValue);

            md5.Clear();

            string sTemp = "";

            for (int i = 0; i < bytHash.Length; i++)

            {

                sTemp += bytHash[i].ToString("X").PadLeft(2, '0');

            }

            return sTemp.ToLower();

        }
    }
}
